package com.spring.shiro.service;

import com.spring.shiro.entity.Role;
import com.spring.shiro.entity.RoleMenu;
import com.spring.shiro.entity.RoleWithMenu;
import com.spring.shiro.mapper.RoleMapper;
import com.spring.shiro.mapper.RoleMenuMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleMenuService roleMenuService;

    public List<Role> findUserRole(String userName) {
        return this.roleMapper.findUserRole(userName);
    }

    public List<Role> findAllRole(Role role) {
        Example example = new Example(Role.class);
        if (StringUtils.isNotBlank(role.getRoleName())){
            example.createCriteria().andCondition("role_name=",role.getRoleName());
        }
        example.setOrderByClause("create_time");

        List<Role> roles = roleMapper.selectByExample(example);

        return roles;
    }

    public RoleWithMenu findRoleWithMenus(Long roleId) {
        List<RoleWithMenu> list = this.roleMapper.findById(roleId);

        List<Long> menuList = list.stream().map(RoleWithMenu::getMenuId).collect(Collectors.toList());
        if (list.isEmpty()) return null;

        RoleWithMenu roleWithMenu = list.get(0);
        roleWithMenu.setMenuIds(menuList);

        return roleWithMenu;
    }

    public Role findByName(String roleName) {
        Example example = new Example(Role.class);
        example.createCriteria().andCondition("lower(role_name)=", roleName.toLowerCase());
        List<Role> list = this.roleMapper.selectByExample(example);

        return list.isEmpty() ? null : list.get(0);
    }

    @Transactional
    public void addRole(Role role, Long[] menuIds) {
        role.setCreateTime(new Date());
        //插入权限表
        this.roleMapper.insert(role);
        //保存角色菜单表信息
        setRoleMenus(role, menuIds);
    }

    public void updateRole(Role role, Long[] menuId) {
        //修改role实体
        role.setModifyTime(new Date());
        roleMapper.updateByPrimaryKeySelective(role);

        //先根据role_id删除中间表数据
        Example example = new Example(RoleMenu.class);
        example.createCriteria().andCondition("role_id=", role.getRoleId());
        this.roleMenuMapper.deleteByExample(example);

        //在插入新的权限数据
        this.setRoleMenus(role,menuId);
    }

    //公用:保存rolemenu中间表数据
    private void setRoleMenus(Role role, Long[] menuIds) {
        Arrays.stream(menuIds).forEach(menuId -> {
            RoleMenu rm = new RoleMenu();
            rm.setMenuId(menuId);
            rm.setRoleId(role.getRoleId());
            this.roleMenuMapper.insert(rm);
        });
    }

    @Transactional
    public void deleteRoles(String roleIds) {
        //删除角色表中数据
        List<String> list = Arrays.asList(roleIds.split(","));
        Example example = new Example(Role.class);
        example.createCriteria().andIn("roleId", list);
        this.roleMapper.deleteByExample(example);

        //再根据roleIds删除角色和菜单表的中间表数据
        this.roleMenuService.deleteRoleMenusByRoleId(roleIds);

        //最后根据roleIds删除用户角色表的中间表数据
        this.userRoleService.deleteUserRolesByRoleId(roleIds);

    }


}
